//open a file ,count every word and figure out the line-number of the word occurs,besides,it offers a search function which return the line-sentence! 
#include <vector>
#include <string>
#include <map>
#include <set>
#include <fstream>
#include <sstream>
#include <iostream>
using namespace std;
typedef vector<string>::size_type line_no;

class TextQuery {
public:
	void read_file(ifstream &is) {                         //read words from a file
		 store_file(is);                                    //store a whole sentence on a each line in  vector<string>  
	     build_map();                                       //build a map that contains the line-number of a word 
	}
	set<line_no> run_query(const string&) const;            //return the line-number of the word you search
	string text_line(line_no) const;                        //return the sentence on the line you search
	
private:
	void store_file(ifstream&);
	void build_map();
	vector<string> lines_of_text;
	map<string,set<line_no> > word_map;
};

void TextQuery::store_file(ifstream& in) {
	string sentence;
	while(getline(in,sentence)) {
		lines_of_text.push_back(sentence);
	}
}

void TextQuery::build_map() {
	for(line_no line_num=0;line_num!=lines_of_text.size();++line_num) {
		istringstream ist(lines_of_text[line_num]);
		string word;
		while(ist >> word) {
			word_map[word].insert(line_num);                             
		}
	}	
}

set<line_no> TextQuery::run_query(const string& word) const {
	map<string,set<line_no> >::const_iterator it=word_map.find(word);
	if(it!=word_map.end()) {
		return it->second;
	} else {
		return set<line_no> ();                                         //besides return an empty set,is there another way to return? 
	}                                                                   //it is somewhat similar to the line 37 in file PhoneBook.h.
}

string TextQuery::text_line(line_no line_num) const {
    if(line_num <= lines_of_text.size()) 
		return lines_of_text[line_num-1];
	cerr << "Line number out of range" << endl;
}
